package com.flyduck.service.impl;

import com.flyduck.domain.SysRole;
import com.flyduck.domain.SysRoleMenu;
import com.flyduck.mapper.SysMenuMapper;
import com.flyduck.mapper.SysRoleMapper;
import com.flyduck.mapper.SysRoleMenuMapper;
import com.flyduck.service.SysRoleService;
import com.flyduck.vo.PageResult;
import com.flyduck.vo.QueryVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @program: flyduck-admin
 * @description:
 * @author: flyduck
 * @create: 2020-05-07 09:58
 **/
@Service
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;

    /**
     * 获取所有的角色
     * @return
     */
    @Override
    public List<SysRole> findList() {
        return sysRoleMapper.findList();
    }

    /**
     * 分页查询
     * @param queryVo
     * @return
     */
    @Override
    public PageResult findPage(QueryVo queryVo) {
        //分页查询
        PageHelper.startPage(queryVo.getPage(),queryVo.getRows());
        Page<SysRole> sysRolePage = sysRoleMapper.findPage(queryVo.getKeyword());
        //返回分页结果集
        PageResult pageResult = new PageResult();
        pageResult.setTotal(sysRolePage.getTotal());
        pageResult.setRows(sysRolePage.getResult());
        return pageResult;
    }

    /**
     * 保存角色
     * @param sysRole
     */
    @Override
    public void save(SysRole sysRole) {
        //保存角色
        sysRoleMapper.insertSelective(sysRole);
        //easyui默认父级菜单不选中,获取每个元素对应的所有父级菜单
        Set<Long> parentIds = new HashSet<>();
        for (Long menuId : sysRole.getMenuIds()) {
            Set<Long> ids = findParentIds(menuId);
            parentIds.addAll(ids);
            parentIds.add(menuId);
        }
        sysRole.setMenuIds(parentIds.toArray(new Long[0]));
        //保存角色菜单关系
        for (Long menuId : sysRole.getMenuIds()) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(sysRole.getId());
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenuMapper.insertSelective(sysRoleMenu);
        }
    }

    /**
     * 思路，获取上一级的id，然后调用此方法获取上一级的id加在一起
     * @param menuId
     * @return
     */
    private Set<Long> findParentIds(Long menuId) {
        Set<Long> ids = new HashSet<>();
        Long prentId = sysMenuMapper.getParentIdById(menuId);
        if(prentId != 0){
            ids.add(prentId);
            Set<Long> parentIds = findParentIds(prentId);
            ids.addAll(parentIds);
        }
        return ids;
    }

    /**
     * 更新角色
     * @param sysRole
     */
    @Override
    public void update(SysRole sysRole) {
        //解除角色菜单关系
        sysRoleMenuMapper.deleteByRoleId(sysRole.getId());
        //更新角色
        sysRoleMapper.updateByPrimaryKeySelective(sysRole);
        //easyui默认父级菜单不选中,获取每个元素对应的所有父级菜单
        Set<Long> parentIds = new HashSet<>();
        for (Long menuId : sysRole.getMenuIds()) {
            Set<Long> ids = findParentIds(menuId);
            parentIds.addAll(ids);
            parentIds.add(menuId);
        }
        sysRole.setMenuIds(parentIds.toArray(new Long[0]));
        //保存角色菜单关系
        for (Long menuId : sysRole.getMenuIds()) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(sysRole.getId());
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenuMapper.insertSelective(sysRoleMenu);
        }

    }

    /**
     * 删除角色
     * @param id
     */
    @Override
    public void deleteById(Long id) {
        //解除角色菜单关系
        sysRoleMenuMapper.deleteByRoleId(id);
        //删除角色
        sysRoleMapper.deleteByPrimaryKey(id);
    }

    /**
     * 根据角色id查询角色
     * @param id
     * @return
     */
    @Override
    public SysRole getRoleById(Long id) {
        //根据角色id查询角色
        SysRole sysRole = sysRoleMapper.getRoleById(id);
        //查询角色菜单对应关系
        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuMapper.findByRoleIds(sysRole.getId());
        Long[] menuIds = sysRoleMenuList.stream()
                .filter(sysRoleMenu -> sysMenuMapper.getMenuById(sysRoleMenu.getMenuId()).getType() ==2)
                .map(SysRoleMenu::getMenuId).toArray(Long[]::new);
        sysRole.setMenuIds(menuIds);
        return sysRole;
    }

    /**
     * 启用/禁用角色
     * @param id
     * @param enabled
     */
    @Override
    public void updateStatus(Long id, Boolean enabled) {
        sysRoleMapper.updateStatus(id,enabled);
    }

    /**
     * 根据用户id查询角色
     * @param userId
     * @return
     */
    @Override
    public List<SysRole> getRolesByUserId(Long userId) {
       return   sysRoleMapper.getRolesByUserId(userId);

    }
}
